Los datos

A continuación se muestran los datos cargados y seleccionado para el analsis. Previmente se limpian las direcciones para mejorar el exito de la geocodificación. Existen 6595 ventas en la base de datos que cubren el periodo 2015-01-09 al 2017-03-15.

ventas_area_geo %>%head()

Estadisticas

Por cliente

Se identificaron 557 clientes diferentes con base es sus nombres, dirección, ciudad y tipo de cliente. La tabla muestra el numero de compras de cada cliente, el total de ventas

clientes_dir 

Histigrama de cantidad de ventas por valor de la factura

ggplot(ventas_area_geo, aes(x=valor_factura))+geom_histogram(bins = 100) 

Clientes ordenados por volumen de ventas

clientes_dir %>% 
  head(70) %>%
ggplot( aes(x= reorder( cliente_mod,-total_ventas),total_ventas, fill=tipo_cliente))+
  geom_bar(stat = "identity")+theme_classic()+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))+
  labs(title="Top 70 clientes volumen de ventas")

clientes_dir %>% 
ggplot( aes(x= reorder( cliente_mod,-total_ventas),total_ventas, fill=tipo_cliente))+
  geom_bar(stat = "identity")+theme_classic()+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))+
  facet_grid(tipo_cliente~)
Error: unexpected ')' in:
"  theme(axis.text.x = element_text(angle = 90, hjust = 1))+
  facet_grid(tipo_cliente~)"

Ventas por tipos de cliente

ggplot(ventas_area_geo, aes(x=tipo_cliente,y=valor_factura))+
  geom_boxplot() + coord_flip() 

ggplot(ventas_area_geo, aes(x=tipo_cliente,y=valor_factura, color= tipo_cliente))+
geom_jitter(position = position_jitter(0.2),alpha=0.2)+ 
  stat_summary(fun.y = mean, geom = "point", shape = 18, size = 3, color = "blue")+
  coord_flip()+ scale_color_brewer(palette="Dark2") +theme_minimal()

Ventas por tipos de cliente por ciudad

ggplot(ventas_area_geo, aes(x=tipo_cliente,y=valor_factura, color= tipo_cliente))+
  geom_jitter(position = position_jitter(0.2),alpha=0.2)+ 
  stat_summary(fun.y = mean, geom = "point", shape = 18, size = 3, color = "blue")+
  coord_flip()+ 
  scale_color_brewer(palette="Dark2") +
  theme_minimal()+
  facet_wrap(~ciudad_mod,ncol = 3)

Ventas por fecha

Por tipo de cliente

En la figura se muestra el cada una de las ventas hechas por un tipo de cliente en cualquier ciudad en esa fecha.

ggplot(ventas_area_geo,aes(x=fecha,y=valor_factura,color=tipo_cliente))+
  geom_point(alpha=0.5,size=1)+
  facet_wrap(~tipo_cliente)

Mapa de calor de las ventas totales por fecha

calendar_tetris_data(min(ventas_fecha$fecha), max(ventas_fecha$fecha))%>% 
  left_join(ventas_fecha,by=c("date"="fecha")) %>% 
  ggplot() + 
  geom_tile(aes(x=week, y=sday, fill = ventas), colour = "grey") + 
  #scale_fill_gradientn(colours = c("#D61818","#FFAE63","#FFFFBD","#B5E384"), na.value='transparent') +
  scale_fill_viridis(na.value="transparent", option = "viridis", direction = -1)+
  geom_segment(aes(x=x, xend=x, y=ymin, yend=ymax)) +                       # (a)
  geom_segment(aes(x=xmin, xend=xmax, y=y, yend=y)) +                       # (b)
  geom_segment(aes(x=dec.x, xend=dec.x, y=dec.ymin, yend=dec.ymax)) +       # (c)
  geom_segment(aes(x=nye.xmin, xend=nye.xmax, y=nye.y, yend=nye.y)) +       # (d)
  geom_segment(x=-0.5, xend=51.5, y=7.5, yend=7.5) +                        # put a line along the top
  geom_segment(x=0.5, xend=52.5, y=0.5, yend=0.5) +                         # put a line along the bottom
  geom_text(aes(x=month.x, y=month.y, label=month.l), hjust=0.25) +         # (e)
  scale_x_continuous(expand=c(0.01,0.01)) +                                 # remove excessive left+right padding 
  coord_equal()+theme_classic()+
  theme(axis.title.y=element_blank(), axis.title.x=element_blank(),         # remove axis titles
        panel.grid.major=element_blank(), panel.grid.minor=element_blank(), # remove gridlines 
        legend.title=element_blank(),                                       # remove legend title
        axis.text.x=element_blank(), axis.ticks.x=element_blank()           # remove x-axis labels and ticks
  ) + 
  facet_wrap(~ year, ncol = 1)

Datos de clientes geocodificados

Los datos de cada cliente geocodificados usando el API de Google en R son de la siguiente forma:

clientes_geocoded %>% head()

En total fueron geodoficicados existosamente 501 de 557. Queda por verificar si existen codificcione que son falsos positivos mediante un proceso de verificación.

Mapa de clientes por ciudad

El area del circulo es proporcional a las ventas de cada cliente

clientes_geocoded %>% 
qmplot(data=. ,lon, lat, maptype = "toner-lite", color = ciudad_mod,size=total_ventas,)
Using zoom = 8...
Ignoring unknown parameters: NA

Ventas en Cali Por cliente

En Cali fueron realizadas 1506 en el periodo que fueron georeferenciadas. El intervalo de tiempo de estas ventas es desde 2015-01-14 al 2017-03-15.

Ventas georeferenciadas

El tamano es propocional al valor de la factura

qmplot(data= ventas_cali,lon, lat, maptype = "toner-lite", geom="blank") +
  geom_point(alpha=0.3,color="turquoise3",aes(size=valor_factura,color=tipo_cliente))
Using zoom = 13...

Ventas georreferenciadas por tipos de cliente

qmplot(data= ventas_cali,lon, lat, maptype = "toner-lite", geom="blank") +
    geom_point(alpha=0.3,aes(size=valor_factura,color=tipo_cliente))+
    facet_wrap(~tipo_cliente)
Using zoom = 13...

ventas_cali %>% 
  qmplot(data= .,lon, lat, maptype = "toner-lite", geom="blank")+ 
  #geom_density2d(data =ventas_cali ,aes(x = lon, y = lat), size = 0.3) +
  stat_density2d(data = ventas_cali,  
                 aes(x = lon, y = lat, fill = ..level.., alpha = ..level..), 
                 size = 0.01, bins = 16, geom = "polygon") + 
  scale_fill_viridis(option = "plasma", direction = 1) + 
  scale_alpha(range = c(0.1, 0.4), guide = FALSE)+
  facet_wrap(~tipo_cliente)
Using zoom = 13...

LS0tCnRpdGxlOiAiVmVudGFzIE1hcnF1ZXRlcmlhIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgojIExvcyBkYXRvcwoKQSBjb250aW51YWNpw7NuIHNlIG11ZXN0cmFuIGxvcyBkYXRvcyBjYXJnYWRvcyB5IHNlbGVjY2lvbmFkbyBwYXJhIGVsIGFuYWxzaXMuIFByZXZpbWVudGUgc2UgbGltcGlhbiBsYXMgZGlyZWNjaW9uZXMgcGFyYSBtZWpvcmFyIGVsIGV4aXRvIGRlIGxhIGdlb2NvZGlmaWNhY2nDs24uIEV4aXN0ZW4gYHIgbnJvdyh2ZW50YXNfYXJlYV9nZW8pYCB2ZW50YXMgZW4gbGEgYmFzZSBkZSBkYXRvcyBxdWUgY3VicmVuIGVsIHBlcmlvZG8gYHIgbWluKHZlbnRhc19hcmVhX2dlbyRmZWNoYSlgIGFsIGByIG1heCh2ZW50YXNfYXJlYV9nZW8kZmVjaGEpYC4KYGBge3IgZGF0b3NfY3J1ZG9zLCBlY2hvPVRSVUV9CnZlbnRhc19hcmVhX2dlbyAlPiVoZWFkKCkKYGBgCgoKIyBFc3RhZGlzdGljYXMKIyMgUG9yIGNsaWVudGUKU2UgaWRlbnRpZmljYXJvbiBgciBucm93KGNsaWVudGVzX2RpcilgIGNsaWVudGVzIGRpZmVyZW50ZXMgY29uIGJhc2UgZXMgc3VzIG5vbWJyZXMsIGRpcmVjY2nDs24sIGNpdWRhZCB5IHRpcG8gZGUgY2xpZW50ZS4gTGEgdGFibGEgbXVlc3RyYSBlbCBudW1lcm8gZGUgY29tcHJhcyBkZSBjYWRhIGNsaWVudGUsIGVsIHRvdGFsIGRlIHZlbnRhcyAKYGBge3IgZWNobz1UUlVFfQpjbGllbnRlc19kaXIgCmBgYAoKCiMjIEhpc3RpZ3JhbWEgZGUgY2FudGlkYWQgZGUgdmVudGFzIHBvciB2YWxvciBkZSBsYSBmYWN0dXJhCmBgYHtyfQpnZ3Bsb3QodmVudGFzX2FyZWFfZ2VvLCBhZXMoeD12YWxvcl9mYWN0dXJhKSkrZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwMCkgCmBgYAoKIyMgQ2xpZW50ZXMgb3JkZW5hZG9zIHBvciB2b2x1bWVuIGRlIHZlbnRhcwoKYGBge3IgLCBmaWcuaGVpZ2h0PTExfQpjbGllbnRlc19kaXIgJT4lIAogIGhlYWQoNzApICU+JQpnZ3Bsb3QoIGFlcyh4PSByZW9yZGVyKCBjbGllbnRlX21vZCwtdG90YWxfdmVudGFzKSx0b3RhbF92ZW50YXMsIGZpbGw9dGlwb19jbGllbnRlKSkrCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpK3RoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSsKICBsYWJzKHRpdGxlPSJUb3AgNzAgY2xpZW50ZXMgdm9sdW1lbiBkZSB2ZW50YXMiKQpgYGAKYGBge3J9CmNsaWVudGVzX2RpciAlPiUgCmdncGxvdCggYWVzKHg9IHJlb3JkZXIoIGNsaWVudGVfbW9kLC10b3RhbF92ZW50YXMpLHRvdGFsX3ZlbnRhcywgZmlsbD10aXBvX2NsaWVudGUpKSsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikrdGhlbWVfY2xhc3NpYygpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpKwogIGZhY2V0X2dyaWQodGlwb19jbGllbnRlfikKICBsYWJzKHRpdGxlPSJjbGllbnRlcyB2b2x1bWVuIGRlIHZlbnRhcyIpCmBgYAoKCiMjIFZlbnRhcyBwb3IgdGlwb3MgZGUgY2xpZW50ZQpgYGB7ciBmaWcuYWxpZ249ImNlbnRlciJ9CmdncGxvdCh2ZW50YXNfYXJlYV9nZW8sIGFlcyh4PXRpcG9fY2xpZW50ZSx5PXZhbG9yX2ZhY3R1cmEpKSsKICBnZW9tX2JveHBsb3QoKSArIGNvb3JkX2ZsaXAoKSAKYGBgCgpgYGB7cn0KZ2dwbG90KHZlbnRhc19hcmVhX2dlbywgYWVzKHg9dGlwb19jbGllbnRlLHk9dmFsb3JfZmFjdHVyYSwgY29sb3I9IHRpcG9fY2xpZW50ZSkpKwpnZW9tX2ppdHRlcihwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcigwLjIpLGFscGhhPTAuMikrIAogIHN0YXRfc3VtbWFyeShmdW4ueSA9IG1lYW4sIGdlb20gPSAicG9pbnQiLCBzaGFwZSA9IDE4LCBzaXplID0gMywgY29sb3IgPSAiYmx1ZSIpKwogIGNvb3JkX2ZsaXAoKSsgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IkRhcmsyIikgK3RoZW1lX21pbmltYWwoKQpgYGAKCgojIyBWZW50YXMgcG9yIHRpcG9zIGRlIGNsaWVudGUgcG9yIGNpdWRhZApgYGB7ciAsZmlnLmhlaWdodD0gMTB9CmdncGxvdCh2ZW50YXNfYXJlYV9nZW8sIGFlcyh4PXRpcG9fY2xpZW50ZSx5PXZhbG9yX2ZhY3R1cmEsIGNvbG9yPSB0aXBvX2NsaWVudGUpKSsKICBnZW9tX2ppdHRlcihwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcigwLjIpLGFscGhhPTAuMikrIAogIHN0YXRfc3VtbWFyeShmdW4ueSA9IG1lYW4sIGdlb20gPSAicG9pbnQiLCBzaGFwZSA9IDE4LCBzaXplID0gMywgY29sb3IgPSAiYmx1ZSIpKwogIGNvb3JkX2ZsaXAoKSsgCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IkRhcmsyIikgKwogIHRoZW1lX21pbmltYWwoKSsKICBmYWNldF93cmFwKH5jaXVkYWRfbW9kLG5jb2wgPSAzKQpgYGAKCgojIFZlbnRhcyBwb3IgZmVjaGEgCiMgUG9yIHRpcG8gZGUgY2xpZW50ZQpFbiBsYSBmaWd1cmEgc2UgbXVlc3RyYSBlbCBjYWRhIHVuYSBkZSBsYXMgdmVudGFzIGhlY2hhcyBwb3IgdW4gdGlwbyBkZSBjbGllbnRlIGVuIGN1YWxxdWllciBjaXVkYWQgZW4gZXNhIGZlY2hhLgoKYGBge3J9CmdncGxvdCh2ZW50YXNfYXJlYV9nZW8sYWVzKHg9ZmVjaGEseT12YWxvcl9mYWN0dXJhLGNvbG9yPXRpcG9fY2xpZW50ZSkpKwogIGdlb21fcG9pbnQoYWxwaGE9MC41LHNpemU9MSkrCiAgZmFjZXRfd3JhcCh+dGlwb19jbGllbnRlKQpgYGAKCgojIyBNYXBhIGRlIGNhbG9yIGRlIGxhcyB2ZW50YXMgdG90YWxlcyBwb3IgZmVjaGEKYGBge3IsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTh9CmNhbGVuZGFyX3RldHJpc19kYXRhKG1pbih2ZW50YXNfZmVjaGEkZmVjaGEpLCBtYXgodmVudGFzX2ZlY2hhJGZlY2hhKSklPiUgCiAgbGVmdF9qb2luKHZlbnRhc19mZWNoYSxieT1jKCJkYXRlIj0iZmVjaGEiKSkgJT4lIAogIGdncGxvdCgpICsgCiAgZ2VvbV90aWxlKGFlcyh4PXdlZWssIHk9c2RheSwgZmlsbCA9IHZlbnRhcyksIGNvbG91ciA9ICJncmV5IikgKyAKICAjc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3VycyA9IGMoIiNENjE4MTgiLCIjRkZBRTYzIiwiI0ZGRkZCRCIsIiNCNUUzODQiKSwgbmEudmFsdWU9J3RyYW5zcGFyZW50JykgKwogIHNjYWxlX2ZpbGxfdmlyaWRpcyhuYS52YWx1ZT0idHJhbnNwYXJlbnQiLCBvcHRpb24gPSAidmlyaWRpcyIsIGRpcmVjdGlvbiA9IC0xKSsKICBnZW9tX3NlZ21lbnQoYWVzKHg9eCwgeGVuZD14LCB5PXltaW4sIHllbmQ9eW1heCkpICsgICAgICAgICAgICAgICAgICAgICAgICMgKGEpCiAgZ2VvbV9zZWdtZW50KGFlcyh4PXhtaW4sIHhlbmQ9eG1heCwgeT15LCB5ZW5kPXkpKSArICAgICAgICAgICAgICAgICAgICAgICAjIChiKQogIGdlb21fc2VnbWVudChhZXMoeD1kZWMueCwgeGVuZD1kZWMueCwgeT1kZWMueW1pbiwgeWVuZD1kZWMueW1heCkpICsgICAgICAgIyAoYykKICBnZW9tX3NlZ21lbnQoYWVzKHg9bnllLnhtaW4sIHhlbmQ9bnllLnhtYXgsIHk9bnllLnksIHllbmQ9bnllLnkpKSArICAgICAgICMgKGQpCiAgZ2VvbV9zZWdtZW50KHg9LTAuNSwgeGVuZD01MS41LCB5PTcuNSwgeWVuZD03LjUpICsgICAgICAgICAgICAgICAgICAgICAgICAjIHB1dCBhIGxpbmUgYWxvbmcgdGhlIHRvcAogIGdlb21fc2VnbWVudCh4PTAuNSwgeGVuZD01Mi41LCB5PTAuNSwgeWVuZD0wLjUpICsgICAgICAgICAgICAgICAgICAgICAgICAgIyBwdXQgYSBsaW5lIGFsb25nIHRoZSBib3R0b20KICBnZW9tX3RleHQoYWVzKHg9bW9udGgueCwgeT1tb250aC55LCBsYWJlbD1tb250aC5sKSwgaGp1c3Q9MC4yNSkgKyAgICAgICAgICMgKGUpCiAgc2NhbGVfeF9jb250aW51b3VzKGV4cGFuZD1jKDAuMDEsMC4wMSkpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHJlbW92ZSBleGNlc3NpdmUgbGVmdCtyaWdodCBwYWRkaW5nIAogIGNvb3JkX2VxdWFsKCkrdGhlbWVfY2xhc3NpYygpKwogIHRoZW1lKGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksIGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksICAgICAgICAgIyByZW1vdmUgYXhpcyB0aXRsZXMKICAgICAgICBwYW5lbC5ncmlkLm1ham9yPWVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vcj1lbGVtZW50X2JsYW5rKCksICMgcmVtb3ZlIGdyaWRsaW5lcyAKICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgcmVtb3ZlIGxlZ2VuZCB0aXRsZQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSAgICAgICAgICAgIyByZW1vdmUgeC1heGlzIGxhYmVscyBhbmQgdGlja3MKICApICsgCiAgZmFjZXRfd3JhcCh+IHllYXIsIG5jb2wgPSAxKQpgYGAKCiMgRGF0b3MgZGUgY2xpZW50ZXMgZ2VvY29kaWZpY2Fkb3MgCkxvcyBkYXRvcyBkZSBjYWRhIGNsaWVudGUgZ2VvY29kaWZpY2Fkb3MgdXNhbmRvIGVsIEFQSSBkZSBHb29nbGUgZW4gUiBzb24gZGUgbGEgc2lndWllbnRlIGZvcm1hOgpgYGB7cn0KY2xpZW50ZXNfZ2VvY29kZWQgJT4lIGhlYWQoKQpgYGAKCgpFbiB0b3RhbCBmdWVyb24gZ2VvZG9maWNpY2Fkb3MgZXhpc3Rvc2FtZW50ZSBgciBjbGllbnRlc19nZW9jb2RlZCAlPiUgZHJvcF9uYShhZGRyZXNzKSU+JSBucm93KClgIGRlIGByIG5yb3coY2xpZW50ZXNfZ2VvY29kZWQpYC4gUXVlZGEgcG9yIHZlcmlmaWNhciBzaSBleGlzdGVuIGNvZGlmaWNjaW9uZSBxdWUgc29uIGZhbHNvcyBwb3NpdGl2b3MgbWVkaWFudGUgdW4gcHJvY2VzbyBkZSB2ZXJpZmljYWNpw7NuLgoKIyMgTWFwYSBkZSBjbGllbnRlcyBwb3IgY2l1ZGFkCkVsIGFyZWEgZGVsIGNpcmN1bG8gZXMgcHJvcG9yY2lvbmFsIGEgbGFzIHZlbnRhcyBkZSBjYWRhIGNsaWVudGUgCmBgYHtyLCBmaWcuaGVpZ2h0PTE1fQpjbGllbnRlc19nZW9jb2RlZCAlPiUgCnFtcGxvdChkYXRhPS4gLGxvbiwgbGF0LCBtYXB0eXBlID0gInRvbmVyLWxpdGUiLCBjb2xvciA9IGNpdWRhZF9tb2Qsc2l6ZT10b3RhbF92ZW50YXMsKQpgYGAKCiMjIFZlbnRhcyBlbiBDYWxpIFBvciBjbGllbnRlCkVuIENhbGkgZnVlcm9uIHJlYWxpemFkYXMgYHIgbnJvdyh2ZW50YXNfY2FsaSlgIGVuIGVsIHBlcmlvZG8gcXVlIGZ1ZXJvbiBnZW9yZWZlcmVuY2lhZGFzLiBFbCBpbnRlcnZhbG8gZGUgdGllbXBvIGRlIGVzdGFzIHZlbnRhcyBlcyBkZXNkZSBgciBtaW4odmVudGFzX2NhbGkkZmVjaGEpYCBhbCBgciBtYXgodmVudGFzX2NhbGkkZmVjaGEpYC4gCgojVmVudGFzIGdlb3JlZmVyZW5jaWFkYXMKRWwgdGFtYW5vIGVzIHByb3BvY2lvbmFsIGFsIHZhbG9yIGRlIGxhIGZhY3R1cmEKYGBge3IgfQpxbXBsb3QoZGF0YT0gdmVudGFzX2NhbGksbG9uLCBsYXQsIG1hcHR5cGUgPSAidG9uZXItbGl0ZSIsIGdlb209ImJsYW5rIikgKwogIGdlb21fcG9pbnQoYWxwaGE9MC4zLGNvbG9yPSJ0dXJxdW9pc2UzIixhZXMoc2l6ZT12YWxvcl9mYWN0dXJhLGNvbG9yPXRpcG9fY2xpZW50ZSkpCmBgYAoKI1ZlbnRhcyBnZW9ycmVmZXJlbmNpYWRhcyBwb3IgdGlwb3MgZGUgY2xpZW50ZQpgYGB7ciwgZmlnLmhlaWdodD0xM30KcW1wbG90KGRhdGE9IHZlbnRhc19jYWxpLGxvbiwgbGF0LCBtYXB0eXBlID0gInRvbmVyLWxpdGUiLCBnZW9tPSJibGFuayIpICsKICAgIGdlb21fcG9pbnQoYWxwaGE9MC4zLGFlcyhzaXplPXZhbG9yX2ZhY3R1cmEsY29sb3I9dGlwb19jbGllbnRlKSkrCiAgICBmYWNldF93cmFwKH50aXBvX2NsaWVudGUpCmBgYAoKYGBge3IsIGZpZy5oZWlnaHQ9MTN9CnZlbnRhc19jYWxpICU+JSAKICBxbXBsb3QoZGF0YT0gLixsb24sIGxhdCwgbWFwdHlwZSA9ICJ0b25lci1saXRlIiwgZ2VvbT0iYmxhbmsiKSsgCiAgI2dlb21fZGVuc2l0eTJkKGRhdGEgPXZlbnRhc19jYWxpICxhZXMoeCA9IGxvbiwgeSA9IGxhdCksIHNpemUgPSAwLjMpICsKICBzdGF0X2RlbnNpdHkyZChkYXRhID0gdmVudGFzX2NhbGksICAKICAgICAgICAgICAgICAgICBhZXMoeCA9IGxvbiwgeSA9IGxhdCwgZmlsbCA9IC4ubGV2ZWwuLiwgYWxwaGEgPSAuLmxldmVsLi4pLCAKICAgICAgICAgICAgICAgICBzaXplID0gMC4wMSwgYmlucyA9IDE2LCBnZW9tID0gInBvbHlnb24iKSArIAogIHNjYWxlX2ZpbGxfdmlyaWRpcyhvcHRpb24gPSAicGxhc21hIiwgZGlyZWN0aW9uID0gMSkgKyAKICBzY2FsZV9hbHBoYShyYW5nZSA9IGMoMC4xLCAwLjQpLCBndWlkZSA9IEZBTFNFKSsKICBmYWNldF93cmFwKH50aXBvX2NsaWVudGUpCgpgYGAKCgoKCg==